#include <memory>
#include <iostream>
#include <string>
#include "Connection.hpp"
#include "Reactor.hpp"
#include "Socket.hpp"
#include "NetCal.hpp"
#include "InetAddr.hpp"
#include "Listener.hpp"
#include "PackageParse.hpp"
#include "HandlerConnection.hpp"

int main(int argc, char* args[])
{
    if(argc != 2)
    {
        std::cerr<<"./server _port"<<std::endl;
        exit(1);
    }
    uint16_t port = std::stoi(args[1]);
    InetAddr locoladdr("0.0.0.0", port);

    NetCal netcal;
    PackageParse parse(std::bind(&NetCal::Calculator, &netcal, std::placeholders::_1));
    HandlerConnection handlerconns(std::bind(&PackageParse::Excute, &parse, std::placeholders::_1));

    Listener listen(port);
    SetNonBlock(listen.ListenSockfd());

    std::unique_ptr<Reactor> R = std::make_unique<Reactor>();
    R->SetConnect(std::bind(&Listener::Accepter, &listen, std::placeholders::_1));
    R->SetNormalHandler(
        std::bind(&HandlerConnection::HandlerRecver, &handlerconns, std::placeholders::_1),
        std::bind(&HandlerConnection::HandlerSender, &handlerconns, std::placeholders::_1),
        std::bind(&HandlerConnection::HandlerExcepter, &handlerconns, std::placeholders::_1)
    );
    R->AddConnection(listen.ListenSockfd(), EPOLLIN|EPOLLET, locoladdr, ListenConnection);

    try
    {
        R->Dispatcher();
    }
    catch(const std::exception& e)
    {
        std::cerr << e.what() << '\n';
    }
    

    return 0;
}